#include "Object.h"
#include "SceneManager.h"

void Object::Init(const char* ID, const Vector3& position, const Vector3& rotation, const float& scale, const Vector4& color, const int numTexture, Texture** tex, Model* model, Shader* shader, Camera* camera)			  
{
	strcpy(this->ID, ID);
	m_Position = position;
	m_Rotation = rotation;
	m_Scale = scale;
	m_NumTex = numTexture;
	m_Tex = tex;
	m_Model = model;
	m_Shader = shader;
	m_Camera = camera;
	m_Color = color;
}

Vector4 Object::GetColor()
{
	return m_Color;
}

char* Object::GetID()
{
	return this->ID;
}
//
//float* ToFloatVector(Vector4 color)
//{
//	float res[4];
//	res[0] = color.x / 255.0;
//	res[1] = color.y / 255.0;
//	res[2] = color.z / 255.0;
//	res[3] = color.w / 255.0;
//	return res;
//}

void Object::Draw(const Matrix &transform, const bool isFill, Shader* lightCastShader)
{
	Shader* temp = m_Shader;
	if (lightCastShader != NULL)
	{
		m_Shader = lightCastShader;
	}
	
	glUseProgram(m_Shader->program);
	m_Shader->EnableState();
	glBindBuffer(GL_ARRAY_BUFFER, m_Model->vboId);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Model->vboId2);
	SceneManager* SM = SceneManager::GetInstance();
	if (m_Shader->a_position != -1)
	{
		glEnableVertexAttribArray(m_Shader->a_position);
		glVertexAttribPointer(m_Shader->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *) offsetof(Vertex, pos));
	}
	if (m_Shader->u_color != -1 )
	{
		//float* temp = ToFloatVector(m_Color);
		if  (isFill == true)
		{
			float temp[4] = {m_Color.x / 255.0, m_Color.y / 255.0, m_Color.z / 255.0, m_Color.w / 255.0};
			glUniform4fv(m_Shader->u_color,1 , temp );
		}
		else
		{
			float temp[4] = {0.0, 0.0, 0.0, 0.0};
			glUniform4fv(m_Shader->u_color,1 , temp );
		}
	}
	if(m_Shader->a_uv != -1)
	{
		glEnableVertexAttribArray(m_Shader->a_uv);
		glVertexAttribPointer(m_Shader->a_uv, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *) offsetof(Vertex, uv));
	}
	if(m_Shader->a_normal != -1)
	{
		glEnableVertexAttribArray(m_Shader->a_normal);
		glVertexAttribPointer(m_Shader->a_normal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *) offsetof(Vertex, normal));
	}
	if (m_Shader->u_light != -1)
	{
		glUniform3fv(m_Shader->u_light, 1, (float*)&(SM->light->GetPosition()));
	}
	if (m_Shader->u_lightMatWVP != -1)
	{
		glUniformMatrix4fv(m_Shader->u_lightMatWVP, 1, GL_FALSE, (transform * SM->light->GetLightMatWVP(Vector3(0,0,0))).m);
	}
	if (m_Shader->u_MatWVP != -1)
	{
		glUniformMatrix4fv(m_Shader->u_MatWVP, 1,GL_FALSE, (transform * SM->camera->CalculateViewMatrix()).m);
	}
	if (m_Shader->u_MatW != -1)
	{
		glUniformMatrix4fv(m_Shader->u_MatW, 1,GL_FALSE, transform.m);
	}
	if (m_Shader->u_campos != -1)
	{
		glUniform3fv(m_Shader->u_campos, 1 , (float*)&SM->camera->position );
	}
	if (m_Shader->u_time != -1)
	{
		glUniform1f(m_Shader->u_time, Timer::GameTime());
	}

	for (int i = 0; i < m_NumTex; i++)
		{
			if (m_Shader->u_tex[i] != -1)
			{
				glActiveTexture(GL_TEXTURE0 + i);
				glBindTexture(GL_TEXTURE_2D, m_Tex[i]->textureID);
				glUniform1i(m_Shader->u_tex[i], i);
			}
		}

	glDrawElements(GL_TRIANGLES, m_Model->GetNumIndices(), GL_UNSIGNED_SHORT, 0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindTexture(GL_TEXTURE_2D, 0);
	m_Shader = temp;
	m_Shader->DisableState();

}


Object::Object(void)
{
}

Object::~Object(void)
{
}
